<?php

/* ---------------------------------------------------------------------------------------------------------------------------------- */

class ccdsVarCache
{
    private $config;
    private $cache;

    private $enabled=false;
    
    private $id;

/* ---------------------------------------------------------------------------------------------------------------------------------- */

    static function &getInstance( )
    {
        static $obj;

        if ( !$obj )
        {
            $obj=new ccdsVarCache();
        }
        return $obj;
    }

/* ---------------------------------------------------------------------------------------------------------------------------------- */

    function __construct( )
    {
        if ( 'BACKEND' == CCDS_MODE )
            return;

        $config=ccdsConfig::getInstance();

        $this->config=$config->get( 'VARCACHE' );

        if ( false === $this->config['mode'] )
            return;

        if ( 'MEMCACHED' == $this->config['mode'] )
        {
            $this->cache=new ccdsVarCacheMemcached( $this->config['memcached_servers'] );
            $this->enabled=true;
        }
        elseif ( 'APC' == $this->config['mode'] ) {}
        elseif ( 'XCACHE' == $this->config['mode'] )
        {
            $this->cache=new ccdsVarCacheXcache();
            $this->enabled=true;
        }
        $this->id = crc32( $_SERVER['SCRIPT_FILENAME'] );
    }


/* ---------------------------------------------------------------------------------------------------------------------------------- */

    function get( $key )
    {
        if ( false === $this->enabled )
            return false;
        return $this->cache->get( $this->id.$key );
    }

/* ---------------------------------------------------------------------------------------------------------------------------------- */

    function set( $key, $var, $ttl=false )
    {
        if ( false === $this->enabled )
            return false;
        $ttl=false == $ttl ? $this->config['ttl'] : $ttl;
        return $this->cache->set( $this->id.$key, $var, $ttl );
    }

/* ---------------------------------------------------------------------------------------------------------------------------------- */

    function flush( )
    {
        if ( false === $this->enabled )
            return false;
        $this->cache->flush();
    }

/* ---------------------------------------------------------------------------------------------------------------------------------- */

	function printStats() {
        if ( false === $this->enabled )
            return false;
        $this->cache->printStats();
		
	}

/* ---------------------------------------------------------------------------------------------------------------------------------- */

}


/* ---------------------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------------------- */

class ccdsVarCacheMemcached
{



/* ---------------------------------------------------------------------------------------------------------------------------------- */

    private $memcache;

		private $hit = 0;
		private $miss = 0;
		private $update = 0;
		private $old = 0;
		private $set = 0;

    function __construct( $servers )
    {
        $memcache=new Memcache;

        foreach ( $servers as $i => $server )
        {
            $memcache->addServer( $server['host'], $server['port'] ) or die( "MEMCACHE Could not connect to #" . $i );
        }
        $this->memcache=$memcache;
    }

/* ---------------------------------------------------------------------------------------------------------------------------------- */

	function printStats() {
		
		print "\n<br />";
		print "Hits: ".$this->hit."\n<br />";
		print "Missess: ".$this->miss."\n<br />";
		print "Updates: ".$this->update."\n<br />";
		print "Writes: ".$this->set."\n<br />";
		print "Old: ".$this->old."\n<br />";
		
		
	}


/* ---------------------------------------------------------------------------------------------------------------------------------- */

    function get( $key )
    {
        
        //return $this->memcache->get( $key );
        
        
        $not_expired = $this->memcache->get( $key.'_expires' );
        $value = $this->memcache->get( $key );
        if (1 == $not_expired && $value) {
        	$this->hit++;
        	return $value;
        }
				if (!$not_expired && $value) {
					if (1 == $this->memcache->get( $key.'_updating')) {
						$this->old++;
						return $value;
					} else {
						$this->update++;
						$this->memcache->set( $key.'_updating', 1, false, 3 );
					}
				}
				$this->miss++;
        return false;
    }

/* ---------------------------------------------------------------------------------------------------------------------------------- */

    function set( $key, $value, $ttl=false )
    {
				$this->set++;
        $this->memcache->set( $key.'_expires', 1, false, $ttl );
        return $this->memcache->set( $key, $value, false, ($ttl+200) );
    }


/* ---------------------------------------------------------------------------------------------------------------------------------- */

    function flush( )
    {
        $this->memcache->flush();
    }


/* ---------------------------------------------------------------------------------------------------------------------------------- */

}
/* ---------------------------------------------------------------------------------------------------------------------------------- */

class ccdsVarCacheXcache
{
    function get( $key )
    {
        return xcache_get( $key );
    }

    function set( $key, $value, $ttl=false )
    {
        $ttl=false == $ttl ? $this->config['lifetime'] : $ttl;
        return xcache_set( $key, $value, $ttl );
    }

    function flush( ) { }
}
/* ---------------------------------------------------------------------------------------------------------------------------------- */

class ccdsVarCacheAPC
{
    function get( $key )
    {
        return apc_fetch( $key );
    }

    function set( $key, $value, $ttl=false )
    {
        $ttl=false == $ttl ? $this->config['lifetime'] : $ttl;
        return apc_add( $key, $value, $ttl );
    }

    function flush( )
    {
        apc_clear_cache( 'user' );
    }
}
/* ---------------------------------------------------------------------------------------------------------------------------------- */

?>